package gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.ListIterator;
import javax.swing.JComponent;

/**
 * Draws line and bar graphs, controlled by GraphPanel
 * @author Peter Schilling, Jeff Hunter
 */
public class GraphJComponent extends JComponent {

	private ArrayList<Double> points_;
	private double max_,  min_;
	private boolean isBarGraph_;
	private double xSpace_;

	GraphJComponent(boolean isBarGraph) {
		points_ = new ArrayList<Double>();
		max_ = 0;
		min_ = Double.MAX_VALUE;
		isBarGraph_ = isBarGraph;
		xSpace_ = 0.1;
	}

	public void addPoint(double p) {
		if (p > max_)
			max_ = p;
		if (p < min_)
			min_ = p;
		points_.add(p);
		if(!isBarGraph_)
			setPreferredSize(new Dimension((int) (points_.size() * xSpace_ + 100), 0));
		repaint(this.getVisibleRect());
		revalidate();
	}
	
	public void scrollToEnd(){
		scrollRectToVisible(new Rectangle((int)(points_.size() * xSpace_ + 100),0,getSize().width,getSize().height));
	}

	public double[] getPoints() {
		double[] pointArray = new double[points_.size()];
		int i = 0;
		for (ListIterator<Double> itr = points_.listIterator(); itr.hasNext(); i++)
			pointArray[i] = itr.next();
		return pointArray;
	}

	public double getMax() {
		return max_;
	}

	public double getMin() {
		return min_;
	}

	public double getXSpace() {
		return xSpace_;
	}

	public void setXSpace(double xSpace_) {
		this.xSpace_ = xSpace_;
		setPreferredSize(new Dimension((int) (points_.size() * xSpace_), 0));
		repaint();
		revalidate();
	}

	public void deleteAll() {
		points_.clear();
		min_ = 0;
		max_ = 0;
	}

	@Override
	public void paintComponent(Graphics g) {
		try {
			int canvasHeight = getSize().height - 1;
			int[] xVals = new int[points_.size()];
			int[] xPropVals = new int[points_.size()]; //for proportional bottom graph
			int[] yVals = new int[points_.size()];
			Graphics2D gfx = (Graphics2D) g;

			int valIndex = 0;
			for (ListIterator<Double> itr = points_.listIterator(); itr.hasNext(); valIndex++) {
				double currentPoint = itr.next();
				if (isBarGraph_)
					xPropVals[valIndex] = (int) ((double) valIndex * ((double) getSize().width / (double) points_.size())); // for proportional
				xVals[valIndex] = (int) ((double) valIndex * xSpace_);
				yVals[valIndex] = canvasHeight - (int) (((double) (currentPoint - min_) / (max_ - min_)) * (double) canvasHeight);
			// make graph proportional to canvas size
			}
			if (!isBarGraph_) {
				setForeground(Color.green);
				gfx.drawPolyline(xVals, yVals, points_.size());
			} else 
				for (int i = 0; i < points_.size(); i++) {
					gfx.setColor(Color.darkGray);
					gfx.fillRect(xPropVals[i], yVals[i], getSize().width / points_.size(), canvasHeight - yVals[i]);
					gfx.setColor(Color.green);
					gfx.drawRect(xPropVals[i], yVals[i], getSize().width / points_.size(), canvasHeight - yVals[i]);
				}
		} catch (Exception e) { 
			System.err.println("drawing error (zooming out helps this)");
		}
	}
}
